<?php
declare (strict_types = 1);
namespace app\api\controller;

use think\Request;
use think\Exception;
use app\BaseController;
use think\facade\{Db, Cache, Env, Log};

use think\exception\ValidateException;

use app\common\model\{User};
use app\common\validate\{UserValidate};

class LoginController extends BaseController
{
    /** 获取openid */
    public function getOpenId()
    {
        $data = input('');

        $system = getSystemVal();

        $url = "https://api.weixin.qq.com/sns/jscode2session?appid={$system['appid']}&secret={$system['appsecret']}&js_code={$data['wxcode']}&grant_type=authorization_code";
        $res = curl_get($url);
        $res = json_decode($res, TRUE);

        if(isset($res['errcode'])){
            $this->error_back($res['errmsg']);
        }else{
            $this->success_back('获取成功', $res);
        }
    }

    /**
     * 微信登录
     * 错误码:
     * 40001 用户注册失败
     * 40002 用户注册更新识别码失败
     * 报错后会事务回滚 数据库不新增数据
     */
    public function login()
    {
        $data = input('');
        Log::write($data);

        try{
            validate(UserValidate::class)->scene('wxlogin')->check($data);
        }catch(ValidateException $e){
            $this->error_back($e->getError());
        }

        if($data['openid'] == 'undefined'){
            $this->error_back('openid is undefined');
        }

        $userModel = new User();

        Db::startTrans();
        try{
            $userInfo = $userModel->where(['openid' => $data['openid']])->find();

            /** 判断openid是否注册 */
            if(empty($userInfo)){
                if (isset($data['pid']) && $data['pid'] != 0){
                    $data['pid'] = base64_decode($data['pid']);
                }else{
                    $data['pid'] = 0;
                }

                /** 用户注册 */
                $insert = $userModel->allowField(['openid', 'nickname', 'avatar', 'pid', 'mobile'])->save($data);
            
                if($insert === false){
                    throw new Exception(40001);
                }

                $user_id = $userModel->id;
            }else{
                $user_id = $userInfo['id'];
            }

            Db::commit();
        }catch (Exception $e){
            Db::rollback();
            $this->error_back('登录失败，请稍后重试，错误码：'.$e->getMessage());
        }

        $this->success_back('登录成功', ['user_id' => $user_id]);
    }

    /** 微信信息解密 */
    public function decrypt()
    {
        $data = input('post.');

        try{
            validate(UserValidate::class)->scene('decrypt')->check($data);
        }catch(ValidateException $e){
            $this->error_back($e->getError());
        }

        $system = getSystemVal();

        $object = new \wxdecrypt\WXBizDataCrypt($system['appid'], $data['session_key']);
        $errCode = $object->decryptData($data['encrypted_data'], $data['iv'], $datas);

        if($errCode == 0){
            $this->success_back('解密成功', $datas);
        }else{
            $this->error_back('解密失败，errCode:'.$errCode);
        }
    }

    /** 查询微信小程序二维码 */
    public function codeunlimit()
    {
        $access_token = $this->getaccesstoken();
        $data = input('post.');

        try{
            validate(UserValidate::class)->scene('codeunlimit')->check($data);
        }catch(ValidateException $e){
            $this->error_back($e->getError());
        }

        $url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={$access_token}";

        $post_data = [
            'scene' => $data['scene'],
            'page'  => $data['page'],
        ];

        $post_json = json_encode($post_data);
        $result = curl_post($url, $post_json);

        if(json_decode($result, true)){
            $result = json_decode($result, true);
            $this->error_back(['code' => $result['errcode'], 'msg' => $result['errmsg']]);
        } else {
            $jpg = $result;
            // $url = Env::get("root_path") . "/public";
            $url = root_path() . "/public";
            $file_name = "/storage/wxcode/" . md5(date('YmdHis').rand(000, 999)).".jpg";
            $file = fopen($url . $file_name, "w");
            fwrite($file, $jpg);
            fclose($file);
            $this->success_back('查询成功', ['url' => $file_name]);
        } 
    }

    /** 获取access_token（小程序） */
    private function getaccesstoken()
    {
        $system = getSystemVal();

        $access_token = Cache::get('wx_access_token:' . $system['appid']);

        if($access_token){
            return $access_token;
        }else{
            //1.请求url地址
            $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$system['appid']}&secret={$system['appsecret']}";
            $res = curl_get($url);
            $res = json_decode($res, true);

            if(isset($res['errcode']) && $res['errcode']!=0){
                Log::write('AccessTokenError,ErrCode:'.$res['errcode'].',ErrMsg:'.$res['errmsg']);
            }

            $access_token = $res['access_token'];
            Cache::tag('accessToken')->set('wx_access_token:' .  $system['appid'], $access_token, 3600);

            return $access_token;
        }  
    }

    /** 数据库初始化 */
    public function del(){
        $h = 's_';

        Db::execute("truncate table ". $h . "banner");
        Db::execute("truncate table ". $h . "card");
        Db::execute("truncate table ". $h . "card_shop");
        Db::execute("truncate table ". $h . "cash");
        Db::execute("truncate table ". $h . "code");
        Db::execute("truncate table ". $h . "coupon");
        Db::execute("truncate table ". $h . "finance_record");
        Db::execute("truncate table ". $h . "gift");
        Db::execute("truncate table ". $h . "gift_goods");
        Db::execute("truncate table ". $h . "goods");
        Db::execute("truncate table ". $h . "goods_cart");
        Db::execute("truncate table ". $h . "goods_img");
        Db::execute("truncate table ". $h . "goods_group");
        Db::execute("truncate table ". $h . "order");
        Db::execute("truncate table ". $h . "order_card");
        Db::execute("truncate table ". $h . "order_evaluate");
        Db::execute("truncate table ". $h . "order_evaluate_img");
        Db::execute("truncate table ". $h . "order_gift");
        Db::execute("truncate table ". $h . "order_goods");
        Db::execute("truncate table ". $h . "order_group");
        Db::execute("truncate table ". $h . "order_make");
        Db::execute("truncate table ". $h . "order_money");
        Db::execute("truncate table ". $h . "point_record");
        Db::execute("truncate table ". $h . "techn_cate_ids");
        Db::execute("truncate table ". $h . "techn_files");
        Db::execute("truncate table ". $h . "techn_goods");
        Db::execute("truncate table ". $h . "user_shop");
        Db::execute("truncate table ". $h . "users");
    }
}